#include "test.h"
#include <assert.h>

#define STACK_SIZE  1024*10

void *thread1(void *arg)
{
    printf("this is thread %d , say:%s.\n", xthread_self(), (char *)arg);
    printf("this is thread %d , I will sleep 3 s.\n", xthread_self());
    xthread_sleep(3);
    printf("this is thread %d , I will deatch.\n", xthread_self());
    xthread_detach(xthread_self());
    printf("thread %d: sleep done, exit right now\n", xthread_self());
    xthread_exit((void *) 1);
}

void *thread2(void *arg)
{
    printf("this is thread %d , say:%s.\n", xthread_self(), (char *)arg);
    
    int sleep_count = 3;
    while (sleep_count > 0) {
        xthread_usleep(1000 * 100);
        sleep_count--;
    }
    printf("thread %d: sleep done, exit right now\n", xthread_self());
    xthread_exit((void *) 1);
}

int test_thread(int argc, char *argv[])
{
    /* create a thread without attr */
    xthread_t tid0, tid1;
    if (xthread_create(&tid0, NULL, thread1, (void *) "hello, world!") < 0)
        printf("xthread create failed!\n");
    printf("create thread %d ok.\n", tid0);
    void *thread_stack = malloc(STACK_SIZE);
    assert(thread_stack);
    xthread_attr_t attr;
    xthread_attr_init(&attr); // init to default attr
    xthread_attr_setstackaddr(&attr, thread_stack);
    xthread_attr_setstacksize(&attr, STACK_SIZE);
    
    int state;
    xthread_attr_getdetachstate(&attr, &state);
    printf("xthread detach state %d\n", state);
    void *addr;
    xthread_attr_getstackaddr(&attr, &addr);
    printf("xthread stack addr %x\n", addr);
    size_t size;
    xthread_attr_getstacksize(&attr, &size);
    printf("xthread stack size %d\n", size);
    
    xthread_attr_setdetachstate(&attr, XTHREAD_CREATE_DETACHED);
    if (xthread_create(&tid1, &attr, thread2, (void *) "hello, world!") < 0)
        printf("xthread create failed!\n");
    printf("create thread %d ok.\n", tid1);
    
    void *status;
    xthread_join(tid1, &status);
    printf("thread join %d done with status %x.\n", tid1, status);
    xthread_join(tid0, &status);
    printf("thread join %d done with status %x.\n", tid0, status);
    printf("all thread exited, main sleep 1s.\n");
    
    xthread_sleep(1);
    return 0;
}
